package com.brotherly.util;

import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.List;

public class FileSystem
{
    public static ArrayList<String> parsePath(String pathname)
    {
        ArrayList<String> path = new ArrayList<String>();

        String[] result = pathname.split("\\/");
        for (int index = 0; index != result.length; ++index)
        {
            path.add(result[index]);
        }

        return path;
    }

    public static String makePath(List<String> path)
    {
        StringBuilder builder = new StringBuilder();

        for (int index = 0; index != path.size(); ++index)
        {
            if (index != 0)
                builder.append('/');

            builder.append(path.get(index));
        }

        return builder.toString();
    }

    public static int copyFile(File src, File dst) throws IOException
    {
        int bytecount = 0;

        if (dst.exists())
            dst.delete();

        dst.createNewFile();

        FileInputStream input = new FileInputStream(src);
        FileOutputStream output = new FileOutputStream(dst);

        byte[] buffer = new byte[256];

        while (input.available() > 0)
        {
            int count = input.read(buffer);

            output.write(buffer, 0, count);

            bytecount += count;
        }

        output.close();
        input.close();

        return bytecount;
    }

    public static int copyAll(File src, File dst) throws IOException
    {
        int filecount = 0;

        if (src.isFile())
        {
            copyFile(src, dst);
            return 1;
        }

        if (src.isDirectory())
        {
            dst.mkdirs();

            for (File child : src.listFiles())
            {
                File target = new File(dst, child.getCanonicalPath());

                filecount += copyAll(child, target);
            }
        }

        return filecount;
    }

    public static byte[] readBytes(InputStream input)
    {
        byte[] bytes = new byte[256];
        int count = 0;

        ByteArrayOutputStream output = new ByteArrayOutputStream();

        try
        {
            while (true)
            {
                count = input.read(bytes);
                if (count == -1)
                    break;

                output.write(bytes, 0, count);
            }

            output.close();
        }
        catch (Exception e)
        {
            e.printStackTrace();
        }

        return output.toByteArray();
    }

    public static byte[] readBytes(File file)
    {
        byte[] data = null;

        if (file.exists())
        {
            try
            {
                FileInputStream input = new FileInputStream(file);

                data = readBytes(input);

                input.close();
            }
            catch (Exception e)
            {
                e.printStackTrace();
            }
        }

        return data;
    }

    public static String readString(InputStream input, String encoding)
    {
        String content = null;

        byte[] data = readBytes(input);

        if (data != null)
        {
            try
            {
                content = new String(data, encoding);
            }
            catch (Exception e)
            {
                e.printStackTrace();
            }
        }

        return content;
    }

    public static String readString(File file, String encoding)
    {
        String content = null;

        byte[] data = readBytes(file);

        if (data != null)
        {
            try
            {
                content = new String(data, encoding);
            }
            catch (Exception e)
            {
                e.printStackTrace();
            }
        }

        return content;
    }

    public static boolean writeBytes(File file, byte[] data)
    {
        try
        {
            if (file.exists())
                file.delete();

            file.createNewFile();

            FileOutputStream output = new FileOutputStream(file);

            if (data != null)
                output.write(data);

            output.close();

            return true;
        }
        catch (Exception e)
        {
            e.printStackTrace();
        }

        return false;
    }

    public static boolean writeString(File file, String content, String encoding)
    {
        try
        {
            writeBytes(file, content.getBytes(encoding));

            return true;
        }
        catch (Exception e)
        {
            e.printStackTrace();
        }

        return false;
    }

    /**
     * 根据路径删除指定的目录或文件，无论存在与否
     * 
     * @param sPath
     *            要删除的目录或文件
     * @return 删除成功返回 true，否则返回 false。
     */
    public static boolean DeleteFolder(String sPath)
    {
        boolean flag = false;
        File file = new File(sPath);
        // 判断目录或文件是否存在
        if (!file.exists())
        { // 不存在返回 false
            return flag;
        } else
        {
            // 判断是否为文件
            if (file.isFile())
            { // 为文件时调用删除文件方法
                return deleteFile(sPath);
            } else
            { // 为目录时调用删除目录方法
                return deleteDirectory(sPath);
            }
        }
    }

    /**
     * 删除单个文件
     * 
     * @param sPath
     *            被删除文件的文件名
     * @return 单个文件删除成功返回true，否则返回false
     */
    public static boolean deleteFile(String sPath)
    {
        boolean flag = false;
        File file = new File(sPath);
        // 路径为文件且不为空则进行删除
        if (file.isFile() && file.exists())
        {
            file.delete();
            flag = true;
        }
        return flag;
    }

    /**
     * 删除目录（文件夹）以及目录下的文件
     * 
     * @param sPath
     *            被删除目录的文件路径
     * @return 目录删除成功返回true，否则返回false
     */
    public static boolean deleteDirectory(String sPath)
    {
        // 如果sPath不以文件分隔符结尾，自动添加文件分隔符
        if (!sPath.endsWith(File.separator))
        {
            sPath = sPath + File.separator;
        }
        File dirFile = new File(sPath);
        // 如果dir对应的文件不存在，或者不是一个目录，则退出
        if (!dirFile.exists() || !dirFile.isDirectory())
        {
            return false;
        }
        boolean flag = true;
        // 删除文件夹下的所有文件(包括子目录)
        File[] files = dirFile.listFiles();
        for (int i = 0; i < files.length; i++)
        {
            // 删除子文件
            if (files[i].isFile())
            {
                flag = deleteFile(files[i].getAbsolutePath());
                if (!flag)
                    break;
            } // 删除子目录
            else
            {
                flag = deleteDirectory(files[i].getAbsolutePath());
                if (!flag)
                    break;
            }
        }
        if (!flag)
            return false;
        // 删除当前目录
        if (dirFile.delete())
        {
            return true;
        } else
        {
            return false;
        }
    }
}
